var JOs = new Array(); //array of all jsonObject's
var JOc = null; //current jsonObject

function initialize()
{
	xmlConnStack = new Array();
}

function stateChanged()
{
	try 
	{
		if (JOc.xho.readyState == 4)
		{
			JOc = JOs.shift();
			if (typeof JOc != 'undefined')
			{
				setTimeout('JOc.start()', 0);
			}
		}
	} 
	catch(err) 
	{ 
		if (err.name.indexOf('TypeError') != -1)
		{
			JOc = JOs.shift();
			if (typeof JOc != 'undefined')
			{
				setTimeout('JOc.start()', 0)
			}
		}
	}
}

function getPage(url, action)
{
	var JO = new jsonObject(url, action);
		JO.addAction(stateChanged);
	JOs.push(JO);
	stateChanged();
	return JOc;
}

function GetXmlHttpObject() 
{
	if (window.XMLHttpRequest)
	{
		// code for IE7+, Firefox, Chrome, Opera, Safari
		return new XMLHttpRequest();
	}
	else if (window.ActiveXObject)
	{
		// code for IE6, IE5
		alert("This site is not made for the browser you use, but I hope it will work.");
		return new ActiveXObject("Microsoft.XMLHTTP");
	}
	else
	{
		alert("Je browser ondersteunt geen AJAX!");
		document.title = "iCUP - Fout";
		return null;
	}
}

function jsonObject(p_url, p_action)
{
	this.xho = GetXmlHttpObject();
	this.url = p_url;
	this.action = p_action;
	this.result = null;
	this.xho.open("GET", this.url, true);
	this.xho.onreadystatechange = function()
	{
		if (JOc.xho.readyState == 4)
		{
			JOc.loadResult();
			JOc.action();
		}
	};
		
	this.start = function()
	{
		this.xho.send(null);
	}
	
	
	
	this.addAction = function(func)
	{
		var oldonreadystatechange = this.xho.onreadystatechange; 
		
		if (this.xho.addEventListener)
			this.xho.addEventListener('readystatechange', func, false);
		else
		{
			if (this.xho.onreadystatechange == null) 
			{
				this.xho.onreadystatechange = func;
			}
			else 
			{
				this.xho.onreadystatechange = function() 
				{
					if (oldonreadystatechange) 
					{
						oldonreadystatechange();
					}
					func();
				}
			}
		}
	}
	
	this.loadResult = function()
	{
		this.result = evalData(this.xho.responseText);
	}
}

// SELECT, WHERE
function reQuery(Q)
{
	var result = new Array();
	var Qs = Q.substring(Q.indexOf('SELECT ') + 7, Q.indexOf(' WHERE ') == -1 ? Q.length : Q.indexOf(' WHERE ')); //select ... where part
	//var Qi = Q.indexOf('WHERE ') + 6; //current index to start searching for
	var Qw = Q.substring(Q.indexOf('WHERE ') + 6, Q.length); //where .. end part
	
	if (Qs.indexOf("*") == -1)
	{
		return this.where(Qw).select(Qs);
	}
	else
	{
		return this.where(Qw);
	}
}

function selectFromResult(/* string/array: "fieldname1, fieldname2, etc" */ fieldnames)
{
	this.Qresult = new Array();
	
	if (typeof fieldnames == 'string')
	{
		fieldnames = fieldnames.split(", ");
	}
	//alert("SELECT: " + fieldnames);
	
	for (i = 0; i < this.length; i++)
	{
		var joiner = new Object();
		
		for (fi = 0; fi < fieldnames.length; fi++)
		{
			if (typeof this[i][fieldnames[fi]] != 'undefined')
			{
				joiner[fieldnames[fi]] = this[i][fieldnames[fi]];
			}
		}
		
		this.Qresult.push(joiner);
	}
	
	this.Qresult.query = reQuery;
	this.Qresult.select = selectFromResult;
	this.Qresult.where = whereFromResult;
	
	return this.Qresult;
}

function whereFromResult(condition)
{
	this.Qresult = new Array();
	
	condition = condition.replace(/ = /g, '"] ==');
	condition = condition.replace(/ LIKE/g, '"].indexOf(');
	condition = condition.replace(/AND /g, '&& this[i]["');
	condition = condition.replace(/OR /g, '|| this[i]["');
	condition = 'this[i]["' + condition;
	
	alert("WHERE: " + condition);
	
	var aTc = condition.split(/\|\| | &&/);
	
	for (var iTi = 0; iTi < aTc.length; iTi++)
	{
		alert(aTc[iTi]);
	}
	
	for (i = 0; i < this.length; i++)
	{
		if (eval(condition))
		{
			this.Qresult.push(this[i]);
		}
	}
	
	this.Qresult.query = reQuery;
	this.Qresult.select = selectFromResult;
	this.Qresult.where = this.Qresult.and = whereFromResult;
	
	return this.Qresult;
}

// intert data into any HTML style
function outputResult()
{
	
}

/* 
 * model description:
 * for every occurence of datarow in the data object, duplicate the in curly braces enclosed HTML, and replace the in square braces put names.
 * example:
 
<table>
	<tr>
		<th>id</th>
		<th>text</th>
		<th>url</th>
	</tr>
{	<tr>
		<th>[id]</th>
		<th>[text]</th>
		<th>[url]</th>
	</tr>
}</table>
 
 */

function outputData(sTi /* string Target id */, oDv /* object Data value */, sHm /* string HTML model */)
{
	oTl /* object Target link */ = document.getElementById(sTi);
	
	var sRv /* string Result value */ = "";
		sRv += sHm.substring(0, sHm.indexOf("{") != -1 ? sHm.indexOf("{") - 1 : 0);
			// start with the HTML before the first opening curly brace
	
	for (var iDi /* integer Data index */ = 0; iDi < oDv.length; iDi++)
	{
		var sRa /* string Result addition */ = sHm.substring(sHm.indexOf("{") != -1 ? sHm.indexOf("{") + 1 : 0, sHm.indexOf("}") != -1 ? sHm.indexOf("}") - 1 : sHm.length); 
			// copy the HTML between the curly braces
		
			aRa /* array Result addition */ = sRa.match(/\[[^ \]]+\]/gm); 
				// get all stated varnames
			
		for (iRi /* integer Result index */ = 0; iRi < aRa.length; iRi++)
		{
			sRa = sRa.replace(aRa[iRi], oDv[iDi][aRa[iRi].replace(/(\[|\])/g, '')]); 
				// replace the [varname] with the value of the data value : oDv[iDi][varname]
			//alert(aRa[iRi] + " => " + aRa[iRi].replace(/(\[|\])/g, '') + " : " + oDv[iDi][aRa[iRi].replace(/(\[|\])/g, '')] + "\n\n" + sRa);
		}
		
		sRv += sRa; 
			// add the result addition to the result value
	}
	
		sRv += sHm.substring(sHm.indexOf("}") != -1 ? sHm.indexOf("}") + 1 : sHm.length, sHm.length);
			// end with the HTML after the last closing curly brace
	
	oTl.innerHTML = sRv;
		// add the result to the target object's inner HTML
	
	return sRv;
}

function outputInputNData(sTi /* string Target id */, oDv /* object Data value */, sHm /* string HTML model */, sHi /* string HTML inputmodel */)
{
	oTi /* object Target inputs */ = document.createElement("div");
	oTi.setAttribute('id', sTi + "_i");
	oTo /* object Target output */ = document.createElement("div");
	oTo.setAttribute('id', sTi + "_o");
	oTo.setAttribute('model', sHm);
	oTo.setAttribute('source', oDv.source);
	oTp /* object Target parent */ = document.getElementById(sTi);
	oTp.appendChild(oTi);
	oTp.appendChild(oTo);
	
	var sRv /* string Result value */ = "";
		sRv += sHi.replace(/<input /g, "<input onchange=\"outputData('json_d', evalData(document.getElementById('" + sTi + "_o').source), document.getElementById('" + sTi + "_o').model)\" "); 
			// start with the HTML before the first opening curly brace
			
			alert("outputData('json_d', evalData('" + oDv.source + "'), document.getElementById('" + sTi + "_o').model)");
	oTi.innerHTML = sRv;
		// add the result to the target object's inner HTML
	
	outputData(sTi + "_o", oDv, sHm);
	
	return sRv;
}

function evalData(dataText)
{
	var result = eval(dataText);
		result.query = reQuery;
		result.select = selectFromResult;
		result.where = whereFromResult;
		result.source = dataText;
		result.toSource = function()
		{
			return this.source;
		}
		
	return result;
}

